home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / c / net / RCS / gethostnamadr.c,v < prev    next >
Text File  |  1990-03-29  |  10KB  |  512 lines

  1. head     1.5;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.5
  10. date     90.03.29.17.34.16;  author jhh;  state Exp;
  11. branches ;
  12. next     1.4;
  13.  
  14. 1.4
  15. date     88.07.29.17.53.12;  author ouster;  state Exp;
  16. branches ;
  17. next     1.3;
  18.  
  19. 1.3
  20. date     88.07.29.17.00.14;  author ouster;  state Exp;
  21. branches ;
  22. next     1.2;
  23.  
  24. 1.2
  25. date     88.07.25.13.46.32;  author ouster;  state Exp;
  26. branches ;
  27. next     1.1;
  28.  
  29. 1.1
  30. date     88.07.01.15.40.28;  author ouster;  state Exp;
  31. branches ;
  32. next     ;
  33.  
  34.  
  35. desc
  36. @@
  37.  
  38.  
  39. 1.5
  40. log
  41. @if name-server lookup fails then always read /etc/hosts
  42. @
  43. text
  44. @/*
  45.  * Copyright (c) 1985, 1988 Regents of the University of California.
  46.  * All rights reserved.
  47.  *
  48.  * Redistribution and use in source and binary forms are permitted
  49.  * provided that this notice is preserved and that due credit is given
  50.  * to the University of California at Berkeley. The name of the University
  51.  * may not be used to endorse or promote products derived from this
  52.  * software without specific prior written permission. This software
  53.  * is provided ``as is'' without express or implied warranty.
  54.  */
  55.  
  56. #if defined(LIBC_SCCS) && !defined(lint)
  57. static char sccsid[] = "@@(#)gethostnamadr.c    6.33 (Berkeley) 4/13/88";
  58. #endif /* LIBC_SCCS and not lint */
  59.  
  60. #include <sys/param.h>
  61. #include <sys/socket.h>
  62. #include <netinet/in.h>
  63. #include <ctype.h>
  64. #include <netdb.h>
  65. #include <stdio.h>
  66. #include <errno.h>
  67. #include <arpa/inet.h>
  68. #include <arpa/nameser.h>
  69. #include <resolv.h>
  70.  
  71. #define    MAXALIASES    35
  72. #define    MAXADDRS    35
  73.  
  74. static char *h_addr_ptrs[MAXADDRS + 1];
  75.  
  76. static struct hostent host;
  77. static char *host_aliases[MAXALIASES];
  78. static char hostbuf[BUFSIZ+1];
  79. static struct in_addr host_addr;
  80. static char HOSTDB[] = "/etc/hosts";
  81. static FILE *hostf = NULL;
  82. static char hostaddr[MAXADDRS];
  83. static char *host_addrs[2];
  84. static int stayopen = 0;
  85. static char *any();
  86.  
  87. #if PACKETSZ > 1024
  88. #define    MAXPACKET    PACKETSZ
  89. #else
  90. #define    MAXPACKET    1024
  91. #endif
  92.  
  93. typedef union {
  94.     HEADER hdr;
  95.     u_char buf[MAXPACKET];
  96. } querybuf;
  97.  
  98. static union {
  99.     long al;
  100.     char ac;
  101. } align;
  102.  
  103.  
  104. int h_errno;
  105. extern errno;
  106.  
  107. static struct hostent *
  108. getanswer(answer, anslen, iquery)
  109.     querybuf *answer;
  110.     int anslen;
  111.     int iquery;
  112. {
  113.     register HEADER *hp;
  114.     register u_char *cp;
  115.     register int n;
  116.     u_char *eom;
  117.     char *bp, **ap;
  118.     int type, class, buflen, ancount, qdcount;
  119.     int haveanswer, getclass = C_ANY;
  120.     char **hap;
  121.  
  122.     eom = answer->buf + anslen;
  123.     /*
  124.      * find first satisfactory answer
  125.      */
  126.     hp = &answer->hdr;
  127.     ancount = ntohs(hp->ancount);
  128.     qdcount = ntohs(hp->qdcount);
  129.     bp = hostbuf;
  130.     buflen = sizeof(hostbuf);
  131.     cp = answer->buf + sizeof(HEADER);
  132.     if (qdcount) {
  133.         if (iquery) {
  134.             if ((n = dn_expand(answer->buf, eom,
  135.                  cp, (u_char *) bp, buflen)) < 0) {
  136.                 h_errno = NO_RECOVERY;
  137.                 return ((struct hostent *) NULL);
  138.             }
  139.             cp += n + QFIXEDSZ;
  140.             host.h_name = bp;
  141.             n = strlen(bp) + 1;
  142.             bp += n;
  143.             buflen -= n;
  144.         } else
  145.             cp += dn_skipname(cp, eom) + QFIXEDSZ;
  146.         while (--qdcount > 0)
  147.             cp += dn_skipname(cp, eom) + QFIXEDSZ;
  148.     } else if (iquery) {
  149.         if (hp->aa)
  150.             h_errno = HOST_NOT_FOUND;
  151.         else
  152.             h_errno = TRY_AGAIN;
  153.         return ((struct hostent *) NULL);
  154.     }
  155.     ap = host_aliases;
  156.     host.h_aliases = host_aliases;
  157.     hap = h_addr_ptrs;
  158. #if BSD >= 43 || defined(h_addr)    /* new-style hostent structure */
  159.     host.h_addr_list = h_addr_ptrs;
  160. #endif
  161.     haveanswer = 0;
  162.     while (--ancount >= 0 && cp < eom) {
  163.         if ((n = dn_expand(answer->buf, eom, cp,
  164.             (u_char *) bp, buflen)) < 0)
  165.             break;
  166.         cp += n;
  167.         type = _getshort(cp);
  168.          cp += sizeof(u_short);
  169.         class = _getshort(cp);
  170.         cp += sizeof(u_short) + sizeof(u_long);
  171.         n = _getshort(cp);
  172.         cp += sizeof(u_short);
  173.         if (type == T_CNAME) {
  174.             cp += n;
  175.             if (ap >= &host_aliases[MAXALIASES-1])
  176.                 continue;
  177.             *ap++ = bp;
  178.             n = strlen(bp) + 1;
  179.             bp += n;
  180.             buflen -= n;
  181.             continue;
  182.         }
  183.         if (iquery && type == T_PTR) {
  184.             if ((n = dn_expand(answer->buf, eom,
  185.                 cp, (u_char *) bp, buflen)) < 0) {
  186.                 cp += n;
  187.                 continue;
  188.             }
  189.             cp += n;
  190.             host.h_name = bp;
  191.             return(&host);
  192.         }
  193.         if (iquery || type != T_A)  {
  194. #ifdef DEBUG
  195.             if (_res.options & RES_DEBUG)
  196.                 printf("unexpected answer type %d, size %d\n",
  197.                     type, n);
  198. #endif
  199.             cp += n;
  200.             continue;
  201.         }
  202.         if (haveanswer) {
  203.             if (n != host.h_length) {
  204.                 cp += n;
  205.                 continue;
  206.             }
  207.             if (class != getclass) {
  208.                 cp += n;
  209.                 continue;
  210.             }
  211.         } else {
  212.             host.h_length = n;
  213.             getclass = class;
  214.             host.h_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC;
  215.             if (!iquery) {
  216.                 host.h_name = bp;
  217.                 bp += strlen(bp) + 1;
  218.             }
  219.         }
  220.  
  221.         bp += sizeof(align) - ((u_long)bp % sizeof(align));
  222.  
  223.         if (bp + n >= &hostbuf[sizeof(hostbuf)]) {
  224. #ifdef DEBUG
  225.             if (_res.options & RES_DEBUG)
  226.                 printf("size (%d) too big\n", n);
  227. #endif
  228.             break;
  229.         }
  230.         bcopy((char *) cp, *hap++ = bp, n);
  231.         bp +=n;
  232.         cp += n;
  233.         haveanswer++;
  234.     }
  235.     if (haveanswer) {
  236.         *ap = NULL;
  237. #if BSD >= 43 || defined(h_addr)    /* new-style hostent structure */
  238.         *hap = NULL;
  239. #else
  240.         host.h_addr = h_addr_ptrs[0];
  241. #endif
  242.         return (&host);
  243.     } else {
  244.         h_errno = TRY_AGAIN;
  245.         return ((struct hostent *) NULL);
  246.     }
  247. }
  248.  
  249. struct hostent *
  250. gethostbyname(name)
  251.     char *name;
  252. {
  253.     querybuf buf;
  254.     register char *cp;
  255.     int n;
  256.     extern struct hostent *_gethtbyname();
  257.  
  258.     /*
  259.      * disallow names consisting only of digits/dots, unless
  260.      * they end in a dot.
  261.      */
  262.     if (isdigit(name[0]))
  263.         for (cp = name;; ++cp) {
  264.             if (!*cp) {
  265.                 if (*--cp == '.')
  266.                     break;
  267.                 h_errno = HOST_NOT_FOUND;
  268.                 return ((struct hostent *) NULL);
  269.             }
  270.             if (!isdigit(*cp) && *cp != '.') 
  271.                 break;
  272.         }
  273.  
  274.     if ((n = res_search(name, C_IN, T_A, buf.buf, sizeof(buf))) < 0) {
  275. #ifdef DEBUG
  276.         if (_res.options & RES_DEBUG)
  277.             printf("res_search failed\n");
  278. #endif
  279.         return (_gethtbyname(name));
  280.     }
  281.     return (getanswer(&buf, n, 0));
  282. }
  283.  
  284. struct hostent *
  285. gethostbyaddr(addr, len, type)
  286.     char *addr;
  287.     int len, type;
  288. {
  289.     int n;
  290.     querybuf buf;
  291.     register struct hostent *hp;
  292.     char qbuf[MAXDNAME];
  293.     extern struct hostent *_gethtbyaddr();
  294.  
  295.     if (type != AF_INET)
  296.         return ((struct hostent *) NULL);
  297.     (void)sprintf(qbuf, "%d.%d.%d.%d.in-addr.arpa",
  298.         ((unsigned)addr[3] & 0xff),
  299.         ((unsigned)addr[2] & 0xff),
  300.         ((unsigned)addr[1] & 0xff),
  301.         ((unsigned)addr[0] & 0xff));
  302.     n = res_query(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf));
  303.     if (n < 0) {
  304. #ifdef DEBUG
  305.         if (_res.options & RES_DEBUG)
  306.             printf("res_query failed\n");
  307. #endif
  308.         if (errno == ECONNREFUSED)
  309.             return (_gethtbyaddr(addr, len, type));
  310.         return ((struct hostent *) NULL);
  311.     }
  312.     hp = getanswer(&buf, n, 1);
  313.     if (hp == NULL)
  314.         return ((struct hostent *) NULL);
  315.     hp->h_addrtype = type;
  316.     hp->h_length = len;
  317.     h_addr_ptrs[0] = (char *)&host_addr;
  318.     h_addr_ptrs[1] = (char *)0;
  319.     host_addr = *(struct in_addr *)addr;
  320.     return(hp);
  321. }
  322.  
  323. _sethtent(f)
  324.     int f;
  325. {
  326.     if (hostf == NULL)
  327.         hostf = fopen(HOSTDB, "r" );
  328.     else
  329.         rewind(hostf);
  330.     stayopen |= f;
  331. }
  332.  
  333. _endhtent()
  334. {
  335.     if (hostf && !stayopen) {
  336.         (void) fclose(hostf);
  337.         hostf = NULL;
  338.     }
  339. }
  340.  
  341. struct hostent *
  342. _gethtent()
  343. {
  344.     char *p;
  345.     register char *cp, **q;
  346.  
  347.     if (hostf == NULL && (hostf = fopen(HOSTDB, "r" )) == NULL)
  348.         return (NULL);
  349. again:
  350.     if ((p = fgets(hostbuf, BUFSIZ, hostf)) == NULL)
  351.         return (NULL);
  352.     if (*p == '#')
  353.         goto again;
  354.     cp = any(p, "#\n");
  355.     if (cp == NULL)
  356.         goto again;
  357.     *cp = '\0';
  358.     cp = any(p, " \t");
  359.     if (cp == NULL)
  360.         goto again;
  361.     *cp++ = '\0';
  362.     /* THIS STUFF IS INTERNET SPECIFIC */
  363. #if BSD >= 43 || defined(h_addr)    /* new-style hostent structure */
  364.     host.h_addr_list = host_addrs;
  365. #endif
  366.     host.h_addr = hostaddr;
  367.     *((u_long *)host.h_addr) = inet_addr(p);
  368.     host.h_length = sizeof (u_long);
  369.     host.h_addrtype = AF_INET;
  370.     while (*cp == ' ' || *cp == '\t')
  371.         cp++;
  372.     host.h_name = cp;
  373.     q = host.h_aliases = host_aliases;
  374.     cp = any(cp, " \t");
  375.     if (cp != NULL) 
  376.         *cp++ = '\0';
  377.     while (cp && *cp) {
  378.         if (*cp == ' ' || *cp == '\t') {
  379.             cp++;
  380.             continue;
  381.         }
  382.         if (q < &host_aliases[MAXALIASES - 1])
  383.             *q++ = cp;
  384.         cp = any(cp, " \t");
  385.         if (cp != NULL)
  386.             *cp++ = '\0';
  387.     }
  388.     *q = NULL;
  389.     return (&host);
  390. }
  391.  
  392. static char *
  393. any(cp, match)
  394.     register char *cp;
  395.     char *match;
  396. {
  397.     register char *mp, c;
  398.  
  399.     while (c = *cp) {
  400.         for (mp = match; *mp; mp++)
  401.             if (*mp == c)
  402.                 return (cp);
  403.         cp++;
  404.     }
  405.     return ((char *)0);
  406. }
  407.  
  408. struct hostent *
  409. _gethtbyname(name)
  410.     char *name;
  411. {
  412.     register struct hostent *p;
  413.     register char **cp;
  414.     
  415.     _sethtent(0);
  416.     while (p = _gethtent()) {
  417.         if (strcasecmp(p->h_name, name) == 0)
  418.             break;
  419.         for (cp = p->h_aliases; *cp != 0; cp++)
  420.             if (strcasecmp(*cp, name) == 0)
  421.                 goto found;
  422.     }
  423. found:
  424.     _endhtent();
  425.     return (p);
  426. }
  427.  
  428. struct hostent *
  429. _gethtbyaddr(addr, len, type)
  430.     char *addr;
  431.     int len, type;
  432. {
  433.     register struct hostent *p;
  434.  
  435.     _sethtent(0);
  436.     while (p = _gethtent())
  437.         if (p->h_addrtype == type && !bcmp(p->h_addr, addr, len))
  438.             break;
  439.     _endhtent();
  440.     return (p);
  441. }
  442. @
  443.  
  444.  
  445. 1.4
  446. log
  447. @Lint.
  448. @
  449. text
  450. @d236 1
  451. a236 4
  452.         if (errno == ECONNREFUSED)
  453.             return (_gethtbyname(name));
  454.         else
  455.             return ((struct hostent *) NULL);
  456. @
  457.  
  458.  
  459. 1.3
  460. log
  461. @Lint.
  462. @
  463. text
  464. @d121 1
  465. a121 1
  466.             (uchar *) bp, buflen)) < 0)
  467. d127 1
  468. a127 1
  469.          cp += sizeof(u_short) + sizeof(u_long);
  470. d142 1
  471. a142 1
  472.                 cp, (uchar *) bp, buflen)) < 0) {
  473. @
  474.  
  475.  
  476. 1.2
  477. log
  478. @Lint.
  479. @
  480. text
  481. @d91 2
  482. a92 2
  483.             if ((n = dn_expand((char *)answer->buf, eom,
  484.                  cp, bp, buflen)) < 0) {
  485. d120 2
  486. a121 1
  487.         if ((n = dn_expand((char *)answer->buf, eom, cp, bp, buflen)) < 0)
  488. d141 2
  489. a142 2
  490.             if ((n = dn_expand((char *)answer->buf, eom,
  491.                 cp, bp, buflen)) < 0) {
  492. d187 1
  493. a187 1
  494.         bcopy(cp, *hap++ = bp, n);
  495. d254 1
  496. a254 1
  497.     
  498. d262 1
  499. a262 1
  500.     n = res_query(qbuf, C_IN, T_PTR, (char *)&buf, sizeof(buf));
  501. @
  502.  
  503.  
  504. 1.1
  505. log
  506. @Initial revision
  507. @
  508. text
  509. @a211 1
  510.     struct hostent *hp;
  511. @
  512.